<!DOCTYPE html>
<html>
<head>
    <title>Operational Differentiator Circuit</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <canvas id="circuitCanvas" width="600" height="450"></canvas>
    <script>
        const canvas = document.getElementById('circuitCanvas');
        const ctx = canvas.getContext('2d');

        // Style to mimic the hand-drawn look
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 3;
        ctx.lineCap = 'round';
        ctx.lineJoin = 'round';
        ctx.font = 'bold 24px "Comic Sans MS", cursive, sans-serif';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';

        // --- Helper function to draw text ---
        function drawText(text, x, y, align = 'center') {
            ctx.textAlign = align;
            ctx.fillText(text, x, y);
        }

        // --- Helper function to draw a ground symbol ---
        function drawGround(x, y) {
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.lineTo(x, y + 20);
            ctx.moveTo(x - 15, y + 20);
            ctx.lineTo(x + 15, y + 20);
            ctx.moveTo(x - 10, y + 27);
            ctx.lineTo(x + 10, y + 27);
            ctx.moveTo(x - 5, y + 34);
            ctx.lineTo(x + 5, y + 34);
            ctx.stroke();
        }

        // --- Main Drawing Logic ---
        
        // Op-Amp
        const opampX = 270;
        const opampY = 225;
        const opampWidth = 150;
        const opampHeight = 150;
        const invInputY = opampY - opampHeight / 4;
        const nonInvInputY = opampY + opampHeight / 4;
        
        ctx.beginPath();
        ctx.moveTo(opampX, opampY - opampHeight / 2); // Top vertex
        ctx.lineTo(opampX, opampY + opampHeight / 2); // Bottom vertex
        ctx.lineTo(opampX + opampWidth, opampY);      // Output vertex
        ctx.closePath();
        ctx.stroke();

        // Op-Amp terminals (+ and -)
        drawText('-', opampX + 15, invInputY, 'center');
        drawText('+', opampX + 15, nonInvInputY, 'center');

        // Input side (Vin and Capacitor C)
        const inputX = 80;
        ctx.beginPath();
        ctx.moveTo(inputX, invInputY);
        ctx.lineTo(opampX - 80, invInputY);
        ctx.stroke();
        
        // Capacitor C
        const capX1 = opampX - 80;
        const capX2 = opampX - 60;
        ctx.beginPath();
        ctx.moveTo(capX1, invInputY - 20);
        ctx.lineTo(capX1, invInputY + 20);
        ctx.moveTo(capX2, invInputY - 20);
        ctx.lineTo(capX2, invInputY + 20);
        ctx.stroke();
        drawText('C', (capX1 + capX2) / 2, invInputY - 35);

        // Line from capacitor to op-amp
        ctx.beginPath();
        ctx.moveTo(capX2, invInputY);
        ctx.lineTo(opampX, invInputY);
        ctx.stroke();

        // Vin label and ground
        drawText('V', inputX, invInputY + 30, 'left');
        drawText('in', inputX + 13, invInputY + 38, 'left');
        drawGround(inputX + 5, invInputY + 5);

        // Non-inverting input to ground
        ctx.beginPath();
        ctx.moveTo(opampX, nonInvInputY);
        ctx.lineTo(opampX, nonInvInputY + 45);
        ctx.stroke();
        drawGround(opampX, nonInvInputY + 45);

        // Feedback loop (Resistor R)
        const feedbackTopY = 120;
        ctx.beginPath();
        ctx.moveTo(opampX, invInputY);
        ctx.lineTo(opampX, feedbackTopY);
        ctx.lineTo(opampX + opampWidth, feedbackTopY);
        ctx.lineTo(opampX + opampWidth, opampY);
        ctx.stroke();
        
        // Resistor R on the feedback path
        const resX = opampX + 20;
        const resW = opampWidth - 40;
        ctx.beginPath();
        ctx.moveTo(resX, feedbackTopY);
        ctx.lineTo(resX + resW * 0.15, feedbackTopY);
        ctx.lineTo(resX + resW * 0.25, feedbackTopY + 12);
        ctx.lineTo(resX + resW * 0.45, feedbackTopY - 12);
        ctx.lineTo(resX + resW * 0.65, feedbackTopY + 12);
        ctx.lineTo(resX + resW * 0.85, feedbackTopY - 12);
        ctx.lineTo(resX + resW, feedbackTopY);
        
        // Erase the straight line under the resistor
        ctx.save();
        ctx.globalCompositeOperation = 'destination-out';
        ctx.lineWidth = 6;
        ctx.beginPath();
        ctx.moveTo(resX + resW*0.1, feedbackTopY);
        ctx.lineTo(resX + resW*0.9, feedbackTopY);
        ctx.stroke();
        ctx.restore();

        // Draw the resistor zigzag
        ctx.stroke();
        drawText('R', opampX + opampWidth / 2, feedbackTopY - 30);
        
        // Output side (Vout)
        const outputX = opampX + opampWidth;
        ctx.beginPath();
        ctx.moveTo(outputX, opampY);
        ctx.lineTo(outputX + 70, opampY);
        ctx.stroke();
        drawText('V', outputX + 70, opampY + 25, 'left');
        drawText('out', outputX + 83, opampY + 33, 'left');
        drawGround(outputX + 75, opampY + 5);

    </script>
</body>
</html>